home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / tpjr.com / JOYSTICK.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1990-10-22  |  6.1 KB  |  176 lines

  1. unit Joystick;
  2.  
  3. {
  4. Copyright (c) 1989, 1990 David B. Howorth
  5.  
  6. Requires Turbo Pascal 5.0 or later.
  7.  
  8. Unit last revised May 9, 1989.
  9. This comment last revised October 22, 1990.
  10.  
  11. This file, when compiled to disk, creates JOYSTICK.TPU, a Turbo Pascal unit
  12. containing all necessary routines for joystick control.  The routines can
  13. be demonstrated by running the accompanying program JOYDEMO (after first
  14. compiling JOYSTICK.PAS to disk).
  15.  
  16. For further information see the accompanying file, JOYSTICK.DOC.
  17.  
  18. Permission is granted to distribute this file and the accompanying files
  19. (JOYDEMO.PAS and JOYSTICK.DOC) provided (1) all three files are distributed
  20. together and (2) no fee is charged.
  21.  
  22. Permission is granted to include compiled versions of the routines in these
  23. files in any program, commercial or noncommercial, provided only that if the
  24. program is distributed, whether commercially or noncommercially, a copy
  25. (including any documentation) be sent to me; and, if you distribute your
  26. program as shareware, treat me as registered.  My address is 01960 SW Palatine
  27. Hill Road, Portland, Oregon 97219.
  28. }
  29.  
  30. interface
  31.  
  32. procedure ReadJoyA(var XAxis, YAxis : word);
  33. { Reads the X and Y coordinates of Joystick A. }
  34.  
  35. procedure ReadJoyB(var XAxis, YAxis : word);
  36. { Reads the X and Y coordinates of Joystick B. }
  37.  
  38. function ButtonA1 : boolean;
  39. function ButtonA2 : boolean;
  40. function ButtonB1 : boolean;
  41. function ButtonB2 : boolean;
  42. { These four functions return the status (true = in; false = out) of each
  43.   of the buttons on joystick A and B.  On most models, Button #1 is the
  44.   top button. }
  45.  
  46. function JoystickPresent : boolean;
  47. { This function indicates whether a joystick is installed. }
  48.  
  49. implementation
  50.  
  51. uses Dos;
  52.  
  53. type
  54.   ReadJoyProc = procedure(a,b : byte;var c,d : word);
  55.   ButtonFunc = function(a : byte) : boolean;
  56.  
  57. var
  58.   ReadJoy : ReadJoyProc;
  59.   Button : ButtonFunc;
  60.   Reg : Registers;
  61.  
  62. {----------------------------- private routines ----------------------------}
  63.  
  64. function NewBIOS : boolean;
  65. var
  66.   DecadeChar : char absolute $F000:$FFFB;
  67.   YearChar : char absolute $F000:$FFFC;
  68. begin
  69.   NewBIOS := (DecadeChar in ['9','0']) {an optimistic view of software life}
  70.     or ((DecadeChar = '8') and (YearChar in ['4'..'9']));
  71. end;
  72.  
  73. {$F+}
  74.  
  75. procedure OldReadJoy(xbit,ybit : byte; var XAxis, YAxis : word);
  76. begin
  77. inline(
  78.   $BA/$01/$02/    {mov  dx, 201h      ;load dx with joystick port address   }
  79.   $C4/$BE/>XAxis/ {les  di, XAxis[bp] ;load es with segment and di w/offset }
  80.   $8A/$66/<xbit/  {mov  ah, xbit[bp]  ;set appropriate bit in ah            }
  81.   $E8/$0C/$00/    {call SUBR                                                }
  82.   $C4/$BE/>YAxis/ {les  di, YAxis[bp]                                       }
  83.   $8A/$66/<ybit/  {mov  ah, ybit[bp]  ;set appropriate bit in ah            }
  84.   $E8/$02/$00/    {call SUBR                                                }
  85.   $EB/$1D/        {jump short END     ;we're done!                          }
  86.                   {SUBR:              ;first wait, if necessary, until      }
  87.                   {                   ; relevant bit is 0:                  }
  88.   $B9/$FF/$FF/    {       mov  cx, 0ffffh ;fill cx to the brim              }
  89.   $EC/            {WAIT:  in   al, dx     ;get input from port 201h         }
  90.   $84/$E0/        {       test al, ah     ;is the relevant bit 0 yet?       }
  91.   $E0/$FB/        {       loopne WAIT     ;if not, go back to wait          }
  92.  
  93.   $B9/$FF/$FF/    {       mov  cx, 0ffffh ;fill cx to the brim again        }
  94.   $FA/            {       cli             ;disable interrupts               }
  95.   $EE/            {       out  dx, al     ;'nudge' port 201h                }
  96.   $EC/            {AGAIN: in   al, dx     ;get input from port 201h         }
  97.   $84/$E0/        {       test al, ah     ;is the relevant bit 0 yet?       }
  98.   $E0/$FB/        {       loopne AGAIN    ;if not, go back to AGAIN         }
  99.   $FB/            {       sti             ;reenable interrupts              }
  100.   $F7/$D9/        {       neg  cx         ;negative cx                      }
  101.   $81/$C1/$FF/$FF/{       add  cx, 0ffffh ;add 0ffffh back to value in cx   }
  102.   $26/            {       es:             ;segment override                 }
  103.   $89/$0D/        {       mov  [di], cx   ;store value of cx in location    }
  104.                   {                       ; of relevant variable            }
  105.   $C3);           {       ret                                               }
  106.                   {END:                                                     }
  107. end; { OldReadJoy }
  108.  
  109. procedure NewReadJoy(which, meaningless : byte; var XAxis, YAxis : word);
  110. begin
  111.   Reg.ah := $84;
  112.   Reg.dx := 1;
  113.   intr($15,Reg);
  114.   if (which = 1)
  115.     then begin
  116.            XAxis := Reg.ax;
  117.            YAxis := Reg.bx;
  118.          end
  119.     else begin
  120.            XAxis := Reg.cx;
  121.            YAxis := Reg.dx;
  122.          end;
  123. end;
  124.  
  125. function OldButton(mask : byte) : boolean;
  126. begin OldButton := ((port[$201] and mask) = 0); end;
  127.  
  128. function NewButton(mask : byte) : boolean;
  129. begin
  130.   Reg.ah := $84;
  131.   Reg.dx := 0;
  132.   intr($15,Reg);
  133.   NewButton := ((Reg.al and mask) = 0);
  134. end;
  135.  
  136. {$F-}
  137.  
  138. {----------------------------- public routines -----------------------------}
  139.  
  140. procedure ReadJoyA(var XAxis, YAxis : word);
  141. begin ReadJoy(1,2,XAxis, YAxis); end;
  142.  
  143. procedure ReadJoyB(var XAxis, YAxis : word);
  144. begin ReadJoy(4,8,XAxis, YAxis); end;
  145.  
  146. function ButtonA1 : boolean;
  147. begin ButtonA1 := Button($10); end;
  148.  
  149. function ButtonA2 : boolean;
  150. begin ButtonA2 := Button($20); end;
  151.  
  152. function ButtonB1 : boolean;
  153. begin ButtonB1 := Button($40); end;
  154.  
  155. function ButtonB2 : boolean;
  156. begin ButtonB2 := Button($80); end;
  157.  
  158. function JoystickPresent : boolean;
  159. begin
  160.   intr($11,Reg);
  161.   JoystickPresent := ((Reg.ax and $1000) <> 0);
  162. end;
  163.  
  164. {------------------------------ initialization -----------------------------}
  165.  
  166. begin
  167.   if NewBIOS
  168.     then begin                         { use BIOS routines }
  169.            ReadJoy := NewReadJoy;
  170.            Button := NewButton;
  171.          end
  172.     else begin                         { use work-around routines }
  173.            ReadJoy := OldReadJoy;
  174.            Button := OldButton;
  175.          end;
  176. end.